iT邦幫忙

2022 iThome 鐵人賽

DAY 3
0
AI & Data

親手打造推薦系統系列 第 3

Day 03 - 如何用 sklearn 算相似度?看懂這個蛋糕不見的故事就懂了! - 親手打造推薦系統

  • 分享至 

  • xImage
  •  

前一天的文章(Day 02-如何用一個晚上的時間復刻出 Netflix 的「類似影片」功能?)裡面,我們知道要做出「類似影片」的功能,就要找出任兩部影片之間的相似度,再利用相似度的數值做排序,找出最像的影片推薦給使用者。

相似度這個詞非常的模糊,身為人類的我們可以隱隱約約的知道什麼東西跟什麼東西像。但是就算是我們把影片資訊轉換成向量,那到底相似度的計算邏輯是什麼?我們可以怎麼樣用現成的工具來計算相似度呢?

一個蛋糕不見的故事,剛好可以來說明這一件事情。

是誰偷吃了我的蛋糕?

今天早上起來發現我的蛋糕被偷吃了。還好昨晚有目擊者看到有人從冰箱裡拿走了我的蛋糕。

據目擊者的描述,嫌犯是一個眼睛大、臉圓、長尾巴的傢伙。

很快的,我們就鎖定3個嫌疑犯,分別是 Hello Kitty、Pikachu 和 Sonic,每個都很可疑,但每個都說不是他。

https://ithelp.ithome.com.tw/upload/images/20220918/20152556k430eRQZQc.jpg

我們把目擊者看到的人稱作嫌犯X好了。

把他的眼睛、大臉圓、長尾巴的程度都標成 1.0 。然後也幫 3 個嫌犯,測定特徵的程度。如此,每一個人的特徵向量都被做出來了。如下表所示:

https://ithelp.ithome.com.tw/upload/images/20220918/20152556a0iUHX8yKz.jpg

現在只要能夠算出誰和X最像,誰就最有可能是偷吃我蛋糕的傢伙。

有了特徵向量,要怎麼算出犯人是誰?

這裡介紹兩種相似度的算法。

  1. 歐幾里德距離
  2. 餘弦相似度

https://ithelp.ithome.com.tw/upload/images/20220918/20152556akvlJa2kj9.jpg

歐幾里德距離 (Euclidean distance)

就是計算兩點間直線距離。

這應該是最直覺的相似度算法,就把每一個向量當成是空間上的一個點,計算每個點之間的直線距離,越近的就越相似,也就是越趨近於零的就是越相似。

致於怎麼計算兩個點之間的距離,應該不用我再多說!真的要看的話,可以參考這邊

餘弦相似度 (Cosine similarity)

餘弦相似度,簡單來說就是去計算每個向量之間的夾角大小,夾角越小的就相當於是越相似。

這種用在文件的相似性比較上效果較佳,至於它的計算公式也請看這邊

有沒有現成的計算工具可以用?

計算相似度是一個非常常見的事情,很多的機器學習工具都有提供。以下我們使用 sklearn ,來示範怎麼樣計算相似度?

from sklearn.metrics.pairwise import euclidean_distances, cosine_similarity 

# 每個人的特徵向量
x       = [1.0, 1.0, 1.0] # 嫌犯 X 的特徵 
kitty   = [ .2,  .7,  .2] # kitty 的特徵  
pikachu = [ .4,  .8,  .9] # 皮卡丘 的特徵 
sonic   = [ .8,  .8,  .3] # 索尼克 的特徵

# 把特徵向量集合成一個串列,好讓 sklearn 方便直接計算任兩個向量間的相似度
feature_vectors = [x, kitty, pikachu, sonic] # 
print("Feature vectors:")
print(feature_vectors) 
print()

# 計算任兩個向量間的歐幾里德距離
print("Euclidean distances:")
distances_similarity_metrix = euclidean_distances(feature_vectors)
print(distances_similarity_metrix)
print()

# 計算任兩個向量間的餘弦相似度
print("Cosine similarity:")
cosine_similarity_metrix = cosine_similarity(feature_vectors)
print(cosine_similarity_metrix)
print()

只要這個程式執行下去,到底誰是犯人我們馬上就知道了。必定是和嫌犯X餘弦相似度最高的或者是歐幾里德距離裡面最小的。

以下是執行結果:

Feature vectors:
[[1.0, 1.0, 1.0], [0.2, 0.7, 0.2], [0.4, 0.8, 0.9], [0.8, 0.8, 0.3]]

Euclidean distances:
[[0.         1.17046999 0.64031242 0.75498344]
 [1.17046999 0.         0.73484692 0.6164414 ]
 [0.64031242 0.73484692 0.         0.72111026]
 [0.75498344 0.6164414  0.72111026 0.        ]]

Cosine similarity:
[[1.         0.84119102 0.95553309 0.93720088]
 [0.84119102 1.         0.85597974 0.882667  ]
 [0.95553309 0.85597974 1.         0.82819364]
 [0.93720088 0.882667   0.82819364 1.        ]]

這個結果必須要解釋一下。我第一次看的時候也研究了一下,才發現怎麼看?

我用下圖解釋

https://ithelp.ithome.com.tw/upload/images/20220918/20152556KrDlNbvDDX.jpg

由這兩個執行結果,我們可以發現皮卡丘跟嫌犯X的距離最短(0.64031242),在餘弦相似性分數又最高(0.95553309),所以事情的真相只有一個:

蛋糕是被皮卡丘吃掉的

接下來呢?

今天我們用了一個小故事來說明表示什麼叫做特徵向量,也用 sklearn 示範如何計算向量之間的相似性。

下一篇我會解釋要怎麼樣把電影資料轉成特徵向量,會用到如何分詞、萃取特徵等等,感興趣的朋友別忘記明天再來看囉。


上一篇
親手打造推薦系統 Day 02 - 如何用一個晚上的時間復刻出 Netflix 的「類似影片」功能?
下一篇
Day 04 - 電影資訊要怎麼轉成特徵向量呢? - 親手打造推薦系統
系列文
親手打造推薦系統30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言